package com.fdb.efp.nls.api.rest;

import com.alibaba.fastjson.JSONObject;
import com.fdb.basic.framework.core.constant.*;
import com.fdb.basic.framework.core.util.ReflectUtility;
import com.fdb.basic.framework.web.controller.AbstractController;
import com.fdb.efp.e4a.service.facade.SRoleDataRuleService;
import com.fdb.efp.nls.service.facade.AccLoanService;
import com.fdb.efp.nls.service.vo.AccLoanVO;
import com.fdb.efp.nls.service.facade.RscAdjustBillService;
import com.fdb.efp.nls.service.facade.RscRemoveBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;

@RestController
@RequestMapping("/api")
public class AccLoanController extends AbstractController {

	@Autowired
	@Qualifier("accLoanService")
	private AccLoanService accLoanService;
	@Autowired
	@Qualifier("rscAdjustBillService")
	private RscAdjustBillService rscAdjustBillService;
	@Autowired
	@Qualifier("rscRemoveBillService")
	private RscRemoveBillService rscRemoveBillService;

	@Autowired
	@Qualifier("sRoleDataRuleService")
	private SRoleDataRuleService sRoleDataRuleService;

	/**
	 * 列表数据查询
	 * 
	 * @return
	 */
	@RequestMapping(value = "/acc/loans", method = RequestMethod.POST)
	public @ResponseBody ResponseData<List<AccLoanVO>> queryAccLoanAll(@RequestBody AccLoanVO vo) {
		List<AccLoanVO> outputVo = null;
		Map<String,String> dataRuleTypeMap = sRoleDataRuleService.getDataRuleType(httpRequest.getRequestURI(), getUserRoles());
		vo.setPrdCodebyBaseInfo(dataRuleTypeMap == null ? null:dataRuleTypeMap.get(PubConstant.PRD_CODE));
		DataRuleType dataRuleType = DataRuleType.getDataRuleType(dataRuleTypeMap == null ? null:dataRuleTypeMap.get(PubConstant.PERMIS_TYPE));
		setUserInfoToVO(vo);
		// 根据权限方案调用不同的方案进行数据查询
		switch (dataRuleType) {
		case Owner:
			outputVo = accLoanService.queryAllOwner(vo);
			break;
		case CurrOrg:
			outputVo = accLoanService.queryAllCurrOrg(vo);
			break;
		case CurrDownOrg:
			outputVo = accLoanService.queryAllCurrDownOrg(vo);
			break;
		case CurrOwnerPrd:
			outputVo = accLoanService.queryAllCurrOwnerPrd(vo);
			break;
		default:
			outputVo = accLoanService.queryAllOwner(vo);
			break;
		}
		outputVo = this.dealResult(outputVo);
		return getResponseData(outputVo);
	}

	/**
	 * 合同底下所有借据
	 * 
	 * @return
	 */
	@RequestMapping(value = "/acc/cont/loans", method = RequestMethod.POST)
	public @ResponseBody ResponseData<List<AccLoanVO>> queryAccLoanCont(@RequestBody AccLoanVO vo) {
		List<AccLoanVO> outputVo = accLoanService.queryListByCont(vo);
		return getResponseData(outputVo);

	}

	/**is
	 * 根据主键查询详情
	 * 
	 * @return
	 */
	@RequestMapping(value = "/acc/loan/{billNo}", method = RequestMethod.GET)
	public @ResponseBody ResponseData<AccLoanVO> queryByPk(@PathVariable("billNo") String billNo) {
		AccLoanVO inVo = new AccLoanVO();
		inVo.setBillNo(billNo);
		AccLoanVO outputVo = accLoanService.queryByPk(inVo);
		if (Objects.isNull(outputVo)){
			return ResponseData.create(null,ApplicationConstance.FAILURE,"查询借据表结果为空！",false);
		}
		return getResponseData(outputVo);

	}

	/**
	 * 根据主键删除信息
	 * 
	 * @return
	 */
	@RequestMapping(value = "/acc/loan", method = RequestMethod.DELETE)
	public @ResponseBody ResponseData<Integer> deleteByPk(@RequestBody AccLoanVO inAccLoanVo) {
		int outputVo = accLoanService.deleteByPk(inAccLoanVo);
		return getResponseData(outputVo);

	}

	/**
	 * 根据主键更新信息
	 * 
	 * @param inAccLoanVo
	 * @return
	 */
	@RequestMapping(value = "/acc/loan", method = RequestMethod.PUT)
	public @ResponseBody ResponseData<Integer> updateByPk(@RequestBody AccLoanVO inAccLoanVo) {
		int outputVo = accLoanService.updateByPk(inAccLoanVo);
		return getResponseData(outputVo);

	}

	/**
	 * 新增数据
	 * 
	 * @param inAccLoanVo
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/acc/loan", method = RequestMethod.POST)
	public @ResponseBody ResponseData<Integer> insertAccLoan(@RequestBody AccLoanVO inAccLoanVo) throws Exception {
		int outputVo = accLoanService.insertAccLoan(inAccLoanVo);
		return getResponseData(outputVo);

	}

	/**
	 * 【2019D0509】【(问题编号)】
	 * 处理贷款种类字段lendType，产品流程并未对该字段有落值，业务需求不明确。
	 * 但业务需求要求展示。所有产品为"个人综合性消费贷款"
	 */
	private List<AccLoanVO> dealResult(List<AccLoanVO> accLoanVOList){
		if(Objects.nonNull(accLoanVOList) && !accLoanVOList.isEmpty()){
			accLoanVOList.forEach(accLoanVO -> {
				accLoanVO.setLendType("001");
			});
		}
		return accLoanVOList;
	}

	/**
	 *
	 * @param vo
	 * @return
	 */
	@RequestMapping(value = "/acc/loans/by/cust", method = RequestMethod.POST)
	public @ResponseBody ResponseData<List<AccLoanVO>> queryAccLoanByCust(@RequestBody AccLoanVO vo) {
		List<AccLoanVO> outputVo = accLoanService.queryAccLoan(vo);
		return getResponseData(outputVo);

	}


	/**
	 * 条件进行查询未结清借据，以及算出逾期天数——风险分类调整
	 * 
	 * @return
	 */
	@RequestMapping(value = "/acc/loan/days", method = RequestMethod.POST)
	public @ResponseBody ResponseData<List<AccLoanVO>> queryOverdueDays(@RequestBody AccLoanVO vo) {
		List<AccLoanVO> outputVo = null;
		if (!allFieldsIsNull(vo)) {
			setUserInfoToVO(vo);
			List<String> contNos = accLoanService.queryContListByAccStatus();
			if (Objects.nonNull(contNos) && contNos.size() != 0) {
				logger.info("未结清合同号：" + JSONObject.toJSONString(contNos));
				List<String> rscAdjustBillNo = new CopyOnWriteArrayList<>(contNos);// 临时变量存储
				logger.info("临时变量存储信息:" + JSONObject.toJSONString(rscAdjustBillNo));
				if (Objects.nonNull(rscAdjustBillNo)) {
					List<String> rscAdjustBill = rscAdjustBillService.queryBillNo();
					logger.info("判断该合同是否有处于待发起、审批中：" + JSONObject.toJSONString(rscAdjustBill));
					rscAdjustBillNo.removeAll(rscAdjustBill);
					logger.info("移除相同合同号后：" + JSONObject.toJSONString(rscAdjustBillNo));
				}
				// 根据借据号查出借据列表
				logger.info("移除相同合同号后数量：" + rscAdjustBillNo.size());
				vo.setContNos(rscAdjustBillNo);
				logger.info("移除相同合同后信息：" + JSONObject.toJSONString(vo));
				// outputVo = this.executeQueryList("queryByRsc", accLoanService, new
				// Object[]{vo});
				// 根据用户角色获取用户权限方案
				Map<String,String> dataRuleTypeMap = sRoleDataRuleService.getDataRuleType(httpRequest.getRequestURI(), getUserRoles());
				vo.setPrdCodebyBaseInfo(dataRuleTypeMap == null ? null:dataRuleTypeMap.get(PubConstant.PRD_CODE));
		DataRuleType dataRuleType = DataRuleType.getDataRuleType(dataRuleTypeMap == null ? null:dataRuleTypeMap.get(PubConstant.PERMIS_TYPE));
				setUserInfoToVO(vo);
				// 根据权限方案调用不同的方案进行数据查询
				switch (dataRuleType) {
				case Owner:
					outputVo = accLoanService.queryAllOwner(vo);
					break;
				case CurrOrg:
					outputVo = accLoanService.queryAllCurrOrg(vo);
					break;
				case CurrDownOrg:
					outputVo = accLoanService.queryAllCurrDownOrg(vo);
					break;
				default:
					outputVo = accLoanService.queryAllOwner(vo);
					break;
				}
			}
		}
		return getResponseData(outputVo);
	}

	/**
	 * 条件进行查询未结清借据——解除风险分类
	 * 
	 * @return
	 */
	@RequestMapping(value = "/acc/loan/remove", method = RequestMethod.POST)
	public @ResponseBody ResponseData<List<AccLoanVO>> queryByRemove(@RequestBody AccLoanVO vo) {
		List<AccLoanVO> outputVo = null;
		if (!allFieldsIsNull(vo)) {
			setUserInfoToVO(vo);
			vo.setManualIdt(BaseConstant.YES);

			List<String> billNos = accLoanService.queryBillListByAccStatus(vo);
			if (Objects.nonNull(billNos) && billNos.size() != 0) {
				logger.info("未结清借据号：" + JSONObject.toJSONString(billNos));
				List<String> rscAdjustBillNo = new CopyOnWriteArrayList<>(billNos);// 临时变量存储
				logger.info("临时变量存储信息:" + JSONObject.toJSONString(rscAdjustBillNo));
				if (Objects.nonNull(rscAdjustBillNo)) {
					List<String> rscAdjustBill = rscRemoveBillService.queryBillNo();
					logger.info("判断该借据是否有借据处于待发起、审批中：" + JSONObject.toJSONString(rscAdjustBill));
					rscAdjustBillNo.removeAll(rscAdjustBill);
					logger.info("移除相同借据号后：" + JSONObject.toJSONString(rscAdjustBillNo));
				}
				// 根据借据号查出借据列表
				logger.info("移除相同借据号后数量：" + rscAdjustBillNo.size());
				vo.setBillNos(rscAdjustBillNo);
				logger.info("移除相同借据后信息：" + JSONObject.toJSONString(vo));
				// outputVo = this.executeQueryList("queryByRsc", accLoanService, new
				// Object[]{vo});
				// 根据用户角色获取用户权限方案
				Map<String,String> dataRuleTypeMap = sRoleDataRuleService.getDataRuleType(httpRequest.getRequestURI(), getUserRoles());
				vo.setPrdCodebyBaseInfo(dataRuleTypeMap == null ? null:dataRuleTypeMap.get(PubConstant.PRD_CODE));
				DataRuleType dataRuleType = DataRuleType.getDataRuleType(dataRuleTypeMap == null ? null:dataRuleTypeMap.get(PubConstant.PERMIS_TYPE));
				setUserInfoToVO(vo);

				// 根据权限方案调用不同的方案进行数据查询
				switch (dataRuleType) {
				case Owner:
					outputVo = accLoanService.queryAllOwner(vo);
					break;
				case CurrOrg:
					outputVo = accLoanService.queryAllCurrOrg(vo);
					break;
				case CurrDownOrg:
					outputVo = accLoanService.queryAllCurrDownOrg(vo);
					break;
				default:
					outputVo = accLoanService.queryAllOwner(vo);
					break;
				}
				return getResponseData(outputVo);

			}
		}
		return getResponseData(outputVo);
	}

	// 判断前端是否有参数传入，进行条件搜索
	public static boolean allFieldsIsNull(Object obj) {
		if (null == obj)
			return true;
		Field[] fields = obj.getClass().getDeclaredFields();
		Object value;
		for (int i = 0; i < fields.length; i++) {
			try {
				value = ReflectUtility.getObjectFieldValue(obj, fields[i]);
				if (value == null)
					continue;
				if (value instanceof String) {
					String s = (String) value;
					if ("".equals(s.trim()))
						continue;
				}
				if (value instanceof List) {
					List<?> list = (List<?>) value;
					if (list.size() == 0)
						continue;
					int num = 0; // 空值的次数
					for (Object object : list) {
						if (object == null)
							num++;
						if (object instanceof String) {
							String s = (String) object;
							if ("".equals(s.trim()))
								num++;
						}
					}
					if (num == list.size())
						continue;
				}
				if (value.getClass().isPrimitive())
					continue;
				if ("serialVersionUID".equals(fields[i].getName()))
					continue;
				return false;
			} catch (IllegalArgumentException e) {
			}
		}
		return true;
	}
}
